//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once

#include "common.h"
#include "memory.h"

FC_NAMESPACE_BEGIN


// allocator
//
// simple base allocator that redirects all allocate, deallocate
// calls to the equivelent fc::allocate, fc::deallocate functions.

class allocator
{
public:
	void* allocate( size_t n, size_t alignment = 0 )
	{
		return fc::allocate( n, alignment );
	}

	void deallocate( void* ptr, size_t size = 0 )
	{
		fc::deallocate( ptr, size );
	}

	// by default, all allocators are created equal.
	bool operator ==( const allocator& ) { return true; }
	bool operator !=( const allocator& ) { return false; }
};



// zero_allocator
//
// allocator which returns zero-ed memory chunks,
// which may be useful for debugging.

template <class AllocBase = allocator>
class zero_allocator : public AllocBase
{
public:
	void* allocate( size_t n, size_t alignment = 0 )
	{
		void* p = AllocBase::allocate(n);
		::memset(p, 0, n);
		return p;
	}
};


// sso_allocator
//
// allocator for string classes which supports sso (small-string-optimization).
// contains an internal buffer of size 'FC_DEFAULT_STRING_BUFFER_SIZE' by default.

// todo: this should be depricated immediately for "static_allocator" ...?

template <size_t N>
class sso_allocator
{
public:
	void* allocate( size_t n, size_t alignment = 0 )
	{
		if( n <= N )
			return (void*)m_buffer;

		return fc::allocate( n, alignment );
	}

	void deallocate( void* ptr, size_t size = 0 )
	{
		if( ptr && ptr != (void*)m_buffer )
			fc::deallocate( ptr, size );
	}

	void set_buffer( void* ) {}
	void* get_buffer() const { return (void*)m_buffer; }

	sso_allocator& operator =( const sso_allocator& ) { return *this; }

	bool operator ==( const allocator& ) { return false; }
	bool operator ==( const sso_allocator& alloc ) { return false; }

protected:
	char m_buffer[N ? N : 1];
};



FC_NAMESPACE_END


// Many containers are configured to use fixed_allocator types by default
// to remove some template bloat when using fixed containers in addition
// to their standard counterparts. Since we don't use base-class optimization
// trickery for classes with allocators, there is no extra cost by doing so.

#include "fixed_allocator.h"

